package com.tianhe.visitormanagement.server.common;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.MessageToByteEncoder;
import lombok.Data;
import org.springframework.stereotype.Component;

/**
 * 服务器
 *
 * @author
 */
@Data
@Component
public class TCPServer {

    public void run(int port,ChannelHandler channelHandler) {
        // 8080 是你要监听的端口
        EventLoopGroup boosGroup = new NioEventLoopGroup();
        EventLoopGroup workGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(boosGroup, workGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();
                            //入参说明: 读超时时间、写超时时间、所有类型的超时时间、时间格式
//                            pipeline.addLast(new IdleStateHandler(5, 0, 0, TimeUnit.SECONDS));
                            pipeline.addLast(channelHandler);
                            pipeline.addLast("encoder", new MessageToByteEncoder<byte[]>() {
                                @Override
                                protected void encode(ChannelHandlerContext ctx, byte[] msg, ByteBuf out) throws Exception {
                                    out.writeBytes(msg);
                                }
                            });
                            pipeline.addLast(new LengthFieldBasedFrameDecoder(65535
                                    , 0, 2, 0, 2));
                            pipeline.addLast(new LengthFieldPrepender(2));
                        }
                    })
                    .option(ChannelOption.SO_BACKLOG, 128)
                    .childOption(ChannelOption.SO_KEEPALIVE, true);
            System.out.println("服务启动...");
            ChannelFuture channelFuture = bootstrap.bind(port).sync();
            channelFuture.channel().closeFuture().sync();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            workGroup.shutdownGracefully();
            boosGroup.shutdownGracefully();
            System.out.println("服务关闭...");
        }
    }

}
